﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.LIB;
using YArchitech.LIB.YJKControls;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	public partial class PipeFrm : System.Windows.Forms.Form
	{
		public PipeFrm()
		{
			this.InitializeComponent();
			new YJKProcessTools().ShowInTaskbarChange(this);
		}

		public PipeFrm(ExternalCommandData commandData, IList<Pipe> iPipeList)
		{
			this.InitializeComponent();
			new YJKProcessTools().ShowInTaskbarChange(this);
			this.cmmData = commandData;
			this.listPipe = iPipeList;
		}

		private void FrmPipe_Load(object sender, EventArgs e)
		{
			try
			{
				this.uiDoc = this.cmmData.Application.ActiveUIDocument;
				this.Text = "水管编辑-共选中" + this.listPipe.Count + "条水管";
				this.ReadPipeParaInfo();
				this.InitStartParam(this.startParam);
			}
			catch (Exception ex)
			{
				YJKMessageBox.Show(ex.Message);
			}
		}

		private void InitStartParam(JudgePipeParam judgeParam)
		{
			judgeParam.PipeSysType = (ElementId)this.cmbSysPipeType.SelectedValue;
			judgeParam.Diameter = Convert.ToDouble(this.comboBox_DN.Text.Trim());
			judgeParam.StartLevel = (ElementId)this.cmbLevel.SelectedValue;
			judgeParam.Offset = Convert.ToDouble(this.txtOffsetLevel.Text.Trim());
			judgeParam.FluxAdditional = Convert.ToDouble(this.txtFluxAdditional.Text.Trim());
		}

		private void ReadPipeParaInfo()
		{
			this.BindSysType(this.uiDoc.Document, this.listPipe[0]);
			this.BindLevel(this.uiDoc.Document, this.listPipe[0]);
			this.BindParaInfo(this.listPipe[0]);
		}

		private void BindSysType(Autodesk.Revit.DB.Document doc, Pipe pipe)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			List<Element> list = new List<Element>();
			list = filteredElementCollector.OfClass(typeof(PipingSystemType)).ToList<Element>();
			int num = 0;
			int selectedIndex = 0;
			Parameter parameter = pipe.GetParameter(BuiltInParameter.RBS_PIPING_SYSTEM_TYPE_PARAM);
			if (parameter.AsElementId().IntegerValue == -1)
			{
				return;
			}
			List<PipeSysType> list2 = new List<PipeSysType>();
			foreach (Element element in list)
			{
				list2.Add(new PipeSysType
				{
					SysTypeId = element.Id,
					SysTypeName = element.Name
				});
				if (element.Name == doc.GetElementById(parameter.AsElementId()).Name)
				{
					selectedIndex = num;
				}
				num++;
			}
			this.cmbSysPipeType.DataSource = list2;
			this.cmbSysPipeType.ValueMember = "SysTypeId";
			this.cmbSysPipeType.DisplayMember = "SysTypeName";
			this.cmbSysPipeType.SelectedIndex = selectedIndex;
		}

		private void BindLevel(Autodesk.Revit.DB.Document doc, Pipe pipe)
		{
			IEnumerable<Element> enumerable = new FilteredElementCollector(doc).OfClass(typeof(Level)).ToElements();
			int num = 0;
			int selectedIndex = 0;
			List<PipeLevel> list = new List<PipeLevel>();
			foreach (Element element in enumerable)
			{
				Level level = element as Level;
				list.Add(new PipeLevel
				{
					LevelId = level.Id,
					LevelName = level.Name
				});
				if (level.Name == pipe.ReferenceLevel.Name)
				{
					selectedIndex = num;
				}
				num++;
			}
			this.cmbLevel.DataSource = list;
			this.cmbLevel.DisplayMember = "LevelName";
			this.cmbLevel.ValueMember = "LevelId";
			this.cmbLevel.SelectedIndex = selectedIndex;
		}

		private void BindParaInfo(Pipe pipe)
		{
			Segment segment = this.uiDoc.Document.GetElementById(pipe.GetParameter(BuiltInParameter.RBS_PIPE_SEGMENT_PARAM).AsElementId()) as PipeSegment;
			this.comboBox_DN.Items.Clear();
			foreach (MEPSize mepsize in segment.GetSizes())
			{
				this.comboBox_DN.Items.Add(Math.Ceiling(304.7 * mepsize.NominalDiameter).ToString());
			}
			Parameter parameter = pipe.GetParameter(BuiltInParameter.RBS_OFFSET_PARAM);
			this.txtOffsetLevel.Text = Convert.ToDouble(StringTools.CutOffEfficacious(Convert.ToString(UnitConvert.CovertFromAPI(2, parameter.AsDouble()) / 1000.0), (Autodesk.Revit.DB.DisplayUnitType)2)).ToString();
			parameter = pipe.GetParameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM);
			this.comboBox_DN.Text = Convert.ToString(UnitConvert.CovertFromAPI(2, parameter.AsDouble()));
			parameter = pipe.GetParameter(BuiltInParameter.RBS_PIPE_FLOW_PARAM);
			this.txtFlux.Text = StringTools.CutOffEfficacious(Convert.ToString(UnitConvert.CovertFromAPI(64, parameter.AsDouble()) / 3.6), (Autodesk.Revit.DB.DisplayUnitType)2);
			parameter = pipe.GetParameter(BuiltInParameter.RBS_PIPE_ADDITIONAL_FLOW_PARAM);
			this.txtFluxAdditional.Text = Convert.ToDouble(StringTools.CutOffEfficacious((UnitConvert.CovertFromAPI(64, parameter.AsDouble()) / 3.6).ToString(), (Autodesk.Revit.DB.DisplayUnitType)2)).ToString();
			parameter = pipe.GetParameter(BuiltInParameter.RBS_PIPE_VELOCITY_PARAM);
			this.txtSpeed.Text = StringTools.CutOffEfficacious(Convert.ToString(UnitConvert.CovertFromAPI(61, parameter.AsDouble())), (Autodesk.Revit.DB.DisplayUnitType)2);
			parameter = pipe.GetParameter(BuiltInParameter.RBS_PIPE_FRICTION_PARAM);
			this.txtAttrition.Text = StringTools.CutOffEfficacious(Convert.ToString(UnitConvert.CovertFromAPI(38, parameter.AsDouble())), (Autodesk.Revit.DB.DisplayUnitType)2);
			parameter = pipe.GetParameter(BuiltInParameter.RBS_PIPE_PRESSUREDROP_PARAM);
			this.txtRestance.Text = StringTools.CutOffEfficacious(Convert.ToString(UnitConvert.CovertFromAPI(48, parameter.AsDouble())), (Autodesk.Revit.DB.DisplayUnitType)2);
		}

		private void btnExit_Click(object sender, EventArgs e)
		{
			RevitVersionFuncs.ClearSelection(this.uiDoc.Selection);
			base.Dispose();
		}

		private void btnSelectPipe_Click(object sender, EventArgs e)
		{
			try
			{
				base.DialogResult = DialogResult.Retry;
			}
			catch (Exception ex)
			{
				YJKMessageBox.Show(ex.Message);
			}
		}

		private void btnModify_Click(object sender, EventArgs e)
		{
			Transaction transaction = null;
			try
			{
				if (!this.JudgeCheckInfo())
				{
					MessageBox.Show("请勾选需修改的参数！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					return;
				}
				string text = this.comboBox_DN.Text;
				if (!Regex.IsMatch(text, "^[1-9]+\\d*$"))
				{
					MessageBox.Show("直径必须是正整数！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					return;
				}
				if (Convert.ToInt32(text) > 100000)
				{
					MessageBox.Show("请确认输入正确的水管管径！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					return;
				}
				string text2 = this.txtOffsetLevel.Text;
				if (!Regex.IsMatch(text2, "^[+-]?[0-9]+\\d*[.]?\\d*$"))
				{
					MessageBox.Show("偏移量必须是数字！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					return;
				}
				string text3 = this.txtFluxAdditional.Text;
				if (!Regex.IsMatch(text3, "^\\d*[.]?\\d*"))
				{
					MessageBox.Show("附加风量必须是大于0！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					return;
				}
				transaction = new Transaction(this.uiDoc.Document, "修改信息");
				transaction.Start();
				if (this.JudgeModifyPipeInfo(this.listPipe, text, text2, text3))
				{
					MessageBox.Show("修改成功！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					this.uiDoc.Document.Regenerate();
					transaction.Commit();
				}
				else if (this.judgeParam.Diameter == this.startParam.Diameter && this.judgeParam.Offset == this.startParam.Offset && this.judgeParam.PipeSysType == this.startParam.PipeSysType && this.judgeParam.StartLevel == this.startParam.StartLevel && this.judgeParam.FluxAdditional == this.startParam.FluxAdditional)
				{
					MessageBox.Show("您确定不需要修改任何参数？", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Question);
				}
				else
				{
					MessageBox.Show("修改失败！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					transaction.RollBack();
				}
			}
			catch (Exception ex)
			{
				YJKMessageBox.Show(ex.Message);
			}
			finally
			{
				if (transaction != null)
				{
					TransactionStatus status = transaction.GetStatus();
					if (status == 1)
					{
						transaction.Commit();
					}
					else if (status == 5)
					{
						transaction.RollBack();
					}
				}
			}
			base.DialogResult = DialogResult.OK;
		}

		private bool JudgeCheckInfo()
		{
			return this.ckbDiameter.Checked || this.ckbLevel.Checked || this.ckbOffsetLevel.Checked || this.ckbSysPipeType.Checked || this.ckbFluxAdditional.Checked;
		}

		private bool JudgeModifyPipeInfo(IList<Pipe> listPipe, string diameter, string offset, string szFluxAdditional)
		{
			List<bool> list = new List<bool>();
			try
			{
				foreach (Pipe pipe in listPipe)
				{
					if (this.ckbSysPipeType.Checked)
					{
						Parameter parameter = pipe.GetParameter(BuiltInParameter.RBS_PIPING_SYSTEM_TYPE_PARAM);
						list.Add(parameter.Set((ElementId)this.cmbSysPipeType.SelectedValue));
					}
					if (this.ckbLevel.Checked)
					{
						Parameter parameter = pipe.GetParameter(BuiltInParameter.RBS_START_LEVEL_PARAM);
						list.Add(parameter.Set((ElementId)this.cmbLevel.SelectedValue));
					}
					if (this.ckbDiameter.Checked)
					{
						Parameter parameter = pipe.GetParameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM);
						double value = Convert.ToDouble(diameter);
						list.Add(parameter.Set(UnitConvert.CovertToAPI(value, (Autodesk.Revit.DB.DisplayUnitType)2)));
					}
					if (this.ckbOffsetLevel.Checked)
					{
						Parameter parameter = pipe.GetParameter(BuiltInParameter.RBS_OFFSET_PARAM);
						double value = Convert.ToDouble(offset) * 1000.0;
						list.Add(parameter.Set(UnitConvert.CovertToAPI(value, (Autodesk.Revit.DB.DisplayUnitType)2)));
					}
					if (this.ckbFluxAdditional.Checked)
					{
						Parameter parameter = pipe.GetParameter(BuiltInParameter.RBS_PIPE_ADDITIONAL_FLOW_PARAM);
						double value = Convert.ToDouble(szFluxAdditional) * 3.6;
						list.Add(parameter.Set(UnitConvert.CovertToAPI(value, (Autodesk.Revit.DB.DisplayUnitType)64)));
					}
					YJKRevitTools.SetSystemSimple(this.uiDoc.Document, pipe);
				}
			}
			catch (Exception ex)
			{
				YJKMessageBox.Show(ex.Message);
			}
			if (list.Count == 0)
			{
				return false;
			}
			using (List<bool>.Enumerator enumerator2 = list.GetEnumerator())
			{
				while (enumerator2.MoveNext())
				{
					if (!enumerator2.Current)
					{
						return false;
					}
				}
			}
			return true;
		}

		private void txtDiameter_Leave(object sender, EventArgs e)
		{
			if (!Regex.IsMatch(this.comboBox_DN.Text, "^[1-9]+\\d*$"))
			{
				MessageBox.Show("直径必须是正整数！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
				return;
			}
		}

		private void CalculateSpeed()
		{
			double diameter = Convert.ToDouble(this.comboBox_DN.Text) / 1000.0;
			double flux = Convert.ToDouble(this.txtFlux.Text);
			this.txtSpeed.Text = this.GetSpeedValue(diameter, flux);
		}

		private string GetSpeedValue(double diameter, double flux)
		{
			try
			{
				return Convert.ToString(flux / 3600.0 / (2827.4333882308138 * diameter * diameter));
			}
			catch (Exception ex)
			{
				YJKMessageBox.Show(ex.Message);
			}
			return null;
		}

		private void txtOffsetLevel_Leave(object sender, EventArgs e)
		{
			if (!Regex.IsMatch(this.txtOffsetLevel.Text, "^[+-]?[0-9]+\\d*[.]?\\d*$"))
			{
				MessageBox.Show("偏移量必须是数字！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
				return;
			}
		}

		private IList<Pipe> listPipe = new List<Pipe>();

		private ExternalCommandData cmmData;

		private UIDocument uiDoc;

		private JudgePipeParam startParam = new JudgePipeParam();

		private JudgePipeParam judgeParam = new JudgePipeParam();
	}
}
